﻿using System.Collections.Generic;
using System.Threading.Tasks;

namespace DotNetStar.TheKing.Services
{
    /// <summary>
    /// 表示方法执行的结果。
    /// </summary>
    public class ExecutedResult
    {
        /// <summary>
        /// 初始化 <see cref="ExecutedResult"/> 类的新实例。
        /// </summary>
        /// <param name="errors">错误信息。</param>
        protected ExecutedResult(IEnumerable<string> errors):this(false)
            => this.Errors = errors;

        /// <summary>
        /// 初始化 <see cref="ExecutedResult"/> 类的新实例。
        /// </summary>
        /// <param name="success">是否成功。</param>
        protected ExecutedResult(bool success)
            => this.IsSucceed = success; 

        /// <summary>
        /// 获取一个布尔值，表示执行是否成功。
        /// </summary>
        /// <value>
        ///   如果成功则为 <c>true</c>；否则为 <c>false</c>。
        /// </value>
        public bool IsSucceed { get; }

        /// <summary>
        /// 获取错误信息集合。
        /// </summary>
        public IEnumerable<string> Errors { get; } = new HashSet<string>();

        /// <summary>
        /// 表示当前操作是失败的。
        /// </summary>
        /// <param name="errors">失败的错误消息。</param>
        /// <returns></returns>
        public static ExecutedResult Failed(params string[] errors) => new ExecutedResult(errors);

        /// <summary>
        /// 表示当前操作是失败的。
        /// </summary>
        /// <param name="errors">失败的错误消息。</param>
        /// <returns></returns>
        public static ExecutedResult Failed(IEnumerable<string> errors) => new ExecutedResult(errors);

        /// <summary>
        /// 表示当前操作是成功的。
        /// </summary>
        /// <returns></returns>
        public static ExecutedResult Success() => new ExecutedResult(true);
    }

    /// <summary>
    /// 表示一个有泛型返回值的操作结果。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ExecutedResult<T> : ExecutedResult
    {
        /// <summary>
        /// 初始化 <see cref="ExecutedResult{T}"/> 类的新实例。
        /// </summary>
        /// <param name="errors">错误信息。</param>
        protected ExecutedResult(IEnumerable<string> errors) : base(errors)
        {
        }

        /// <summary>
        /// 初始化 <see cref="ExecutedResult{T}"/> 类的新实例。
        /// </summary>
        /// <param name="success">当前操作是否成功。</param>
        protected ExecutedResult(bool success) : base(success)
        {
        }

        /// <summary>
        /// 初始化 <see cref="ExecutedResult{T}"/> 类的新实例。
        /// </summary>
        /// <param name="data">成功后返回的数据。</param>
        protected ExecutedResult(T data) : this(true) => this.Data = data;

        /// <summary>
        /// 获取执行成功后返回的数据。
        /// </summary>
        public T Data { get; }

        /// <summary>
        /// 表示当前操作是失败的。
        /// </summary>
        /// <param name="errors">失败的错误消息。</param>
        /// <returns></returns>
        public static new ExecutedResult<T> Failed(params string[] errors) => new ExecutedResult<T>(errors);
        
        /// <summary>
        /// 表示当前操作是失败的。
        /// </summary>
        /// <param name="errors">失败的错误消息。</param>
        /// <returns></returns>
        public static new ExecutedResult<T> Failed(IEnumerable<string> errors) => new ExecutedResult<T>(errors);

        /// <summary>
        /// 表示当前操作是成功的并返回指定的数据。
        /// </summary>
        /// <returns></returns>
        public static ExecutedResult<T> Success(T data) => new ExecutedResult<T>(data);
    }
}
